package calao.client.ui;

import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.ui.CellPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.client.ui.HasHorizontalAlignment.HorizontalAlignmentConstant;
import com.google.gwt.user.client.ui.HasVerticalAlignment.VerticalAlignmentConstant;

public class SpacerPanel
extends CellPanel
{
	
	public static final int DEFAULT_SPACE_SIZE = 4;

	interface CellManager 
	{
		Element newCell();
		void removeCell(int index);
	}
	
	class RowManager implements CellManager 
	{
		final Element tr = DOM.createTR();
		RowManager()
		{
			DOM.appendChild(getBody(), tr);			
		}
		public Element newCell() 
		{
		    Element td = DOM.createTD();
		    DOM.appendChild(tr, td);
		    return td;
		}
		public void removeCell(int index) 
		{
			Elements.removeChild(tr, index);
		}
	}
	
	class ColumnManager implements CellManager 
	{
		public Element newCell()
		{
			Element tr = DOM.createTR();			
			DOM.appendChild(getBody(), tr);
		    Element td = DOM.createTD();
		    DOM.appendChild(tr, td);
		    return td;
		}
		public void removeCell(int index) 
		{
			Elements.removeChild(getBody(), index);
		}
	}

	public static final int HORIZONTAL = 1;
	public static final int VERTICAL = 2;

	final int type;
	final CellManager boxFactory;

	int spaceSize = DEFAULT_SPACE_SIZE;

	public SpacerPanel(int type)
	{
		this.type = type;
		switch (type) {
		case HORIZONTAL:
			boxFactory = new RowManager();
			break;
		case VERTICAL:
			boxFactory = new ColumnManager();
			break;
		default:
			throw new IllegalArgumentException();
		}
	}

	public void add(Widget widget)
	{
		addBox(widget);
	}

	public void add(Widget widget, HorizontalAlignmentConstant align)
	{
		if (type!=VERTICAL) throw new UnsupportedOperationException();
		Elements.setTextAlign(addBox(widget), align.getTextAlignString());		
	}
	
	public void add(Widget widget, VerticalAlignmentConstant align)
	{
		if (type!=HORIZONTAL) throw new UnsupportedOperationException();
		Elements.setVerticalAlign(addBox(widget), align.getVerticalAlignString());		
	}

	private Element addBox(Widget widget)
	{
		if (getWidgetCount()>0) {
			Element space = boxFactory.newCell();
			if (type==HORIZONTAL) Elements.setWidth(space, spaceSize);
			else Elements.setHeight(space, spaceSize);
		}
		Element box = boxFactory.newCell();
		add(widget, box);
		return box;
	}
	
	public boolean remove(Widget w)
	{
		int widgetIndex = getWidgetIndex(w);
		if (widgetIndex==-1) return false;
		int cellIndex = widgetIndex*2;
		if (widgetIndex>0) {
			boxFactory.removeCell(cellIndex);
			boxFactory.removeCell(cellIndex-1);
		}
		else {
			if (getWidgetCount()>1) boxFactory.removeCell(1);
			boxFactory.removeCell(0);
		}
		super.remove(w);
		return true;
	}

	public int getSpaceSize() 
	{
		return spaceSize;
	}

	public void setSpaceSize(int spaceSize) 
	{
		this.spaceSize = spaceSize;
	}
	
	public void resetSpaceSize()
	{
		spaceSize = DEFAULT_SPACE_SIZE;
	}

}
